package org.szy.monitor.service.impl;


import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryColumn;
import com.mybatisflex.core.query.QueryWrapper;
import org.noear.solon.annotation.Inject;
import org.noear.solon.annotation.ProxyComponent;
import org.szy.core.common.entity.LoginUser;
import org.szy.core.common.enums.CommonStatusEnum;
import org.szy.core.common.enums.UserTypeEnum;
import org.szy.core.common.page.QueryPage;
import org.szy.core.common.service.impl.BaseServiceImpl;
import org.szy.monitor.entity.UserOnline;
import org.szy.monitor.mapper.UserOnlineMapper;
import org.szy.monitor.param.UserOnlineQueryParam;
import org.szy.monitor.service.UserOnlineService;

import java.time.LocalDateTime;

import static org.szy.monitor.entity.table.UserOnlineTableDef.USER_ONLINE;

/**
 * 在线用户记录Service接口实现类
 *
 * @author wangbuhao
 * @since 2023-06-30 17:41:26
 **/
@ProxyComponent
public class UserOnlineServiceImpl extends BaseServiceImpl<UserOnlineMapper, UserOnline> implements UserOnlineService {

    @Inject
    private UserOnlineMapper userOnlineMapper;

    @Override
    public QueryWrapper qwByQuery(UserOnlineQueryParam param) {
        QueryWrapper qw = new QueryWrapper();
        if (StrUtil.isNotEmpty(param.getColumnField())) {
            qw.select(param.getColumnField().split(","));
        }
        qw.and(USER_ONLINE.TOKEN.like(param.getToken()))
                .and(USER_ONLINE.TABLE.like(param.getTable()))
                .and(USER_ONLINE.NICKNAME.like(param.getNickname()))
                .and(USER_ONLINE.IP.like(param.getIp()))
                .and(USER_ONLINE.STATUS.eq(param.getStatus()))
        ;

        return qw;
    }

    @Override
    public Page<UserOnline> page(QueryPage<UserOnline> page, UserOnlineQueryParam param) {
        QueryWrapper qw = qwByQuery(param);

        // 正序排序
        if (StrUtil.isNotEmpty(page.getAscField())) qw.orderBy(page.getAscField().split(","));
        // 倒叙排序
        if (StrUtil.isNotEmpty(page.getDescField())) {
            for (String desc : page.getDescField().split(",")) {
                qw.orderBy(new QueryColumn(desc).desc());
            }
        }

        return this.page(page, qw);
    }

    @Override
    public void online(LoginUser user) {
        UserOnline online = getOne(USER_ONLINE.USER_ID.eq(user.getUserId()).and(USER_ONLINE.TABLE.eq(user.getUserType())).and(USER_ONLINE.TOKEN.eq(user.getToken())));
        if (online == null) {
            online = new UserOnline();
            online.setExpireSecond(user.getExpireSecond());
            online.setToken(user.getToken());
            online.setDevice(user.getDevice());
            online.setActivityDatetime(DateUtil.toLocalDateTime(DateUtil.date(user.getCreateTime())));
            online.setNickname(user.getName());
            online.setStartDatetime(LocalDateTime.now());
            online.setStatus(CommonStatusEnum.ENABLE.getKey());
            online.setUserId(Convert.toLong(user.getUserId()));
            online.setTable(user.getUserType());
            UserTypeEnum typeEnum = UserTypeEnum.findBykey(user.getUserType());
            if (typeEnum != null) {
                online.setTableRemark(typeEnum.getValue());
            }
            online.setBrowser(user.getBrowser());
            online.setOs(user.getOs());
            online.setLocation(user.getLoginLocation());
            online.setIp(user.getIpAddr());
            try {
                save(online);
            } catch (Exception e) {
                this.log.error("", e);
            }
        } else {
            online.setExpireSecond(user.getExpireSecond());
            online.setActivityDatetime(LocalDateTime.now());
            online.setStatus(CommonStatusEnum.ENABLE.getKey());

            updateById(online);
        }

    }

    @Override
    public boolean offline(String token) {
        UserOnline entity = new UserOnline();
        QueryWrapper qw = new QueryWrapper();
        qw.and(USER_ONLINE.TOKEN.eq(token));
        entity.setStatus(CommonStatusEnum.DEACTIVATE.getKey());
        return userOnlineMapper.updateByQuery(entity, qw) > 0;
    }

    @Override
    public void syncActivityTime(String token, LocalDateTime datetime) {
        UserOnline entity = new UserOnline();
        QueryWrapper qw = new QueryWrapper();
        qw.and(USER_ONLINE.TOKEN.eq(token));
        entity.setActivityDatetime(datetime);
        userOnlineMapper.updateByQuery(entity, qw);
    }
}
